package com.deepocean.service.impl;

import com.deepocean.common.entity.ResultEntity;
import com.deepocean.dao.*;
import com.deepocean.entity.BaseEntity;
import com.deepocean.entity.process.*;
import com.deepocean.exception.CoalWashingPlantException;
import com.deepocean.service.IProcessService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

@Service("ProcessServiceConfigImpl")
public class ProcessServiceConfigImpl implements IProcessService {
    @Autowired
    GradingScreenDao gradingScreenDao;
    @Autowired
    JigDao jigDao;
    @Autowired
    CentrifugeDao centrifugeDao;
    @Autowired
    DeslimingScreenDao deslimingScreenDao;
    @Autowired
    HierarchicalCycloneDao hierarchicalCycloneDao;
    @Autowired
    FloatationDao floatationDao;
    @Autowired
    TBSDao tbsDao;
    @Autowired
    LinearScreenDao linearScreenDao;
    @Autowired
    CurvedScreenDao curvedScreenDao;
    @Autowired
    DenseMediumCycloneDao denseMediumCycloneDao;
    @Autowired
    DetachmentScreenDao detachmentScreenDao;
    @Autowired
    CycloneProcessDao cycloneProcessDao;
    @Autowired
    ProcessEngineDao processEngineDao;
    @Autowired
    ProcessRelationDao processRelationDao;

    private static final Double WATER_INPUT_ONE_TON = 5.83;

    private Double cleanCoal = 0.0;
    private Double mediumCoal = 0.0;
    private Double gangue = 0.0;

    private static final String BASE_ENTITY_CLASS_NAME = "com.deepocean.entity.BaseEntity";

    @Override
    public ResultEntity processStart(Double rawCoal) {
        return null;
    }

    @Override
    public ResultEntity processRelation(Double rawCoal, Integer craftType) {

        List<ProcessRelationEntity> processEntityList = processRelationDao.selectByCraftType(craftType);

        ProcessRelationEntity processRelationEntity = processEntityList.stream()
                .filter(entity -> entity.getParentDeviceId().equals("0"))
                .findFirst()
                .orElse(null);

        // 层级结构
        ProcessRelationEntity hierarchy = getHierarchy(processRelationEntity, processEntityList);
        String processId = getRandomId();

        doProcess(hierarchy, rawCoal, null, processId);
        // 总体数据入库
        ProcessEntity processEntity = new ProcessEntity();
        processEntity.setId(processId);
        processEntity.setRawCoal(rawCoal);
        processEntity.setMediaCoal(this.mediumCoal);
        processEntity.setGangue(this.gangue);
        processEntity.setCleanCoal(this.cleanCoal);

        processEngineDao.addProcess(processEntity);

        this.mediumCoal = 0.0;
        this.gangue = 0.0;
        this.cleanCoal = 0.0;

        System.out.println(hierarchy);
        return null;
    }

    @Override
    public boolean updateRelation(List<ProcessRelationEntity> list) {
        Integer craftType = list.stream().map(ProcessRelationEntity::getCraftType).findFirst().orElse(null);
        int count = processRelationDao.selectCountByCraftType(craftType);
        if (count <= 0) {
            // 不存在该工艺，直接插入
            return processRelationDao.add(list);

        } else {
            // 存在，先删除
            boolean flag = processRelationDao.deleteByCraftType(craftType);
            if (!flag) {
                throw new CoalWashingPlantException("com.deepocean.error.1004");
            }
            return processRelationDao.add(list);
        }
    }

    @Override
    public boolean addRelation(List<ProcessRelationEntity> list) {
        return processRelationDao.add(list);
    }

    private synchronized void doProcess(ProcessRelationEntity processRelationEntity, Double input, ProcessRelationEntity parentEntity, String processId) {
        String methodName = processRelationEntity.getMethodName();

        try {
            Method method = this.getClass().getDeclaredMethod(methodName, Double.class, String.class);
            method.setAccessible(true);

            // 调用执行算法
            Object obj = method.invoke(this, input, processId);
            Type type = method.getGenericReturnType();
            String typeName = getFieldName(type.getTypeName());

            nextProcess(typeName, obj, processRelationEntity);

        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            throw new CoalWashingPlantException("com.deepocean.error.1002");
        }
    }

    /**
     *
     * @param typeName 执行设备理论计算的返回类型
     * @param obj 入参对象
     * @param processRelationEntity 当前调用关系
     */
    private void nextProcess(String typeName, Object obj, ProcessRelationEntity processRelationEntity) {
        if (typeName.equals("GradingScreenProcessEntity")) {
            GradingScreenProcessEntity entity =  (GradingScreenProcessEntity) obj;
            invokeNextDevice(processRelationEntity, entity);
        } else if (typeName.equals("CentrifugeProcessEntity")) {
            CentrifugeProcessEntity entity = (CentrifugeProcessEntity) obj;
            invokeNextDevice(processRelationEntity, entity);
        } else if (typeName.equals("CycloneProcessEntity")) {
            CycloneProcessEntity entity = (CycloneProcessEntity) obj;
            invokeNextDevice(processRelationEntity, entity);
        } else if (typeName.equals("DenseMediumCycloneProcessEntity")) {
            DenseMediumCycloneProcessEntity entity = (DenseMediumCycloneProcessEntity) obj;
            invokeNextDevice(processRelationEntity, entity);
        } else if (typeName.equals("DeslimingScreenProcessEntity")) {
            DeslimingScreenProcessEntity entity = (DeslimingScreenProcessEntity) obj;
            invokeNextDevice(processRelationEntity, entity);
        } else if (typeName.equals("DetachmentScreenProcessEntity")) {
            DetachmentScreenProcessEntity entity = (DetachmentScreenProcessEntity) obj;
            invokeNextDevice(processRelationEntity, entity);
        } else if (typeName.equals("FloatationMachineProcessEntity")) {
            FloatationMachineProcessEntity entity = (FloatationMachineProcessEntity) obj;
            invokeNextDevice(processRelationEntity, entity);
        } else if (typeName.equals("HierarchicalCycloneProcessEntity")) {
            HierarchicalCycloneProcessEntity entity = (HierarchicalCycloneProcessEntity) obj;
            invokeNextDevice(processRelationEntity, entity);
        } else if (typeName.equals("JigProcessEntity")) {
            JigProcessEntity entity =  (JigProcessEntity) obj;
            invokeNextDevice(processRelationEntity, entity);
        } else if (typeName.equals("TBSProcessEntity")) {
            TBSProcessEntity entity = (TBSProcessEntity) obj;
            invokeNextDevice(processRelationEntity, entity);
        } else if (typeName.equals("CentrifugeProcessTwoEntity")) {
            CentrifugeProcessTwoEntity entity = (CentrifugeProcessTwoEntity) obj;
            invokeNextDevice(processRelationEntity, entity);
        } else if (typeName.equals("DetachmentScreenProcessTwoEntity")) {
            DetachmentScreenProcessTwoEntity entity = (DetachmentScreenProcessTwoEntity) obj;
            invokeNextDevice(processRelationEntity, entity);
        } else if (typeName.equals("LinearScreenProcessEntity")) {
            LinearScreenProcessEntity entity = (LinearScreenProcessEntity) obj;
            invokeNextDevice(processRelationEntity, entity);
        } else if (typeName.equals("CurvedScreenProcessEntity")) {
            CurvedScreenProcessEntity entity = (CurvedScreenProcessEntity) obj;
            invokeNextDevice(processRelationEntity, entity);
        } else {
            throw new CoalWashingPlantException("com.deepocean.error.1003");
        }
    }

    /**
     * 流程调用下级设备
     * @param processRelationEntity
     * @param entity
     */
    private void invokeNextDevice(ProcessRelationEntity processRelationEntity, BaseEntity entity) {
        List<ProcessRelationEntity> children = processRelationEntity.getChildren();
        if (children == null || children.size() < 0) {
            return;
        }

        for (ProcessRelationEntity child : children) {
            String inputName = child.getInputName();

            List<Field> allFields = getAllField(entity);

            String processId = "";
            // 获取processId
            processId = getProcessId(entity, allFields);
            if (StringUtils.isEmpty(processId)) {
                throw new CoalWashingPlantException("com.deepocean.error.1002");
            }

            for (Field field : allFields) {
                String fieldName = getFieldName(field.getName());
                if (fieldName.equals(inputName)) {
                    try {
                        field.setAccessible(true);
                        Double childInput = (Double) field.get(entity);
                        doProcess(child, childInput, processRelationEntity, processId);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    private String getProcessId(BaseEntity entity, List<Field> allFields) {
        for (Field field : allFields) {
            String fieldName = getFieldName(field.getName());
            if (fieldName.equals("processId")) {
                field.setAccessible(true);
                try {
                    return (String) field.get(entity);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
        return "";
    }

    private String getFieldName(String name) {
        if (StringUtils.isEmpty(name)) {
            throw new CoalWashingPlantException("com.deepocean.error.1002");
        }
        String[] split = name.split("\\.");
        return split[split.length - 1];
    }

    /**
     * 获取BaseEntity的字段
     * @param obj
     * @return
     */
    private List<Field> getAllField (Object obj) {
        Class preClass = obj.getClass();
        List<Field> allFields = getSuperField(preClass, new ArrayList<>());
        return allFields;
    }

    private List<Field> getSuperField(Class preClass, List<Field> fields) {
        Field[] fieldArr = preClass.getDeclaredFields();
        fields.addAll(Arrays.asList(fieldArr));
        if (!BASE_ENTITY_CLASS_NAME.equals(preClass.getName())) {
            getSuperField(preClass.getSuperclass(), fields);
        }
        return fields;
    }

    /**
     * 获取层级结构
     * @param parent
     * @param allList
     * @return
     */
    private ProcessRelationEntity getHierarchy(ProcessRelationEntity parent, List<ProcessRelationEntity> allList) {
        List<ProcessRelationEntity> children = new ArrayList<>();

        allList.forEach(entity -> {
            if (entity.getParentDeviceId().equals(parent.getDeviceId())) {
                children.add(entity);
                getHierarchy(entity, allList);
            }
        });
        parent.setChildren(children);
        return parent;
    }

    /**
     * 脱介筛矸石产出
     * @param input
     * @param processId
     * @return
     */
    private DetachmentScreenProcessTwoEntity detachmentScreenProcessTwo(Double input, String processId) {
        DetachmentScreenProcessTwoEntity detachmentScreenProcessTwoEntity = new DetachmentScreenProcessTwoEntity();
        detachmentScreenProcessTwoEntity.setProcessId(processId);
        detachmentScreenProcessTwoEntity.setId(getRandomId());
        detachmentScreenProcessTwoEntity.setMaterialInput(input);

        // 精煤算法
        BigDecimal bdInput = BigDecimal.valueOf(input);
        BigDecimal bdCleanCoal = bdInput.multiply(BigDecimal.valueOf(0.9));
        double cleanCoal = bdCleanCoal.doubleValue();

        // 矸石算法
        double gangue = bdInput.subtract(bdCleanCoal).doubleValue();

        detachmentScreenProcessTwoEntity.setCleanCoalOutput(cleanCoal);
        detachmentScreenProcessTwoEntity.setMediaOutput(gangue);

        detachmentScreenDao.addTwoProcess(detachmentScreenProcessTwoEntity);

        this.gangue += gangue;

        return detachmentScreenProcessTwoEntity;

    }

    /**
     * 离心机产出精煤设备
     * @param input
     * @param processId
     * @return
     */
    private CentrifugeProcessTwoEntity centrifugeProcessTwo(Double input, String processId) {
        CentrifugeProcessTwoEntity centrifugeProcessTwoEntity = new CentrifugeProcessTwoEntity();
        centrifugeProcessTwoEntity.setMaterialInput(input);
        centrifugeProcessTwoEntity.setId(getRandomId());
        centrifugeProcessTwoEntity.setProcessId(processId);

        // 理论水输出
        BigDecimal bdInput = BigDecimal.valueOf(input);
        BigDecimal bdWater = bdInput.multiply(BigDecimal.valueOf(0.1)).add(BigDecimal.valueOf(WATER_INPUT_ONE_TON));
        double water = bdWater.doubleValue();

        // 精煤产出理论算法
        BigDecimal bdCleanCoal = bdInput.multiply(BigDecimal.valueOf(0.9));
        double cleanCoal = bdCleanCoal.doubleValue();

        centrifugeProcessTwoEntity.setCleanCoalOutput(cleanCoal);
        centrifugeProcessTwoEntity.setWaterOutput(water);

        centrifugeDao.addTwoProcess(centrifugeProcessTwoEntity);

        this.cleanCoal += cleanCoal;

        return centrifugeProcessTwoEntity;
    }

    /**
     * 分级筛流程
     * @param rawCoal
     * @param processId
     * @return
     */
    private GradingScreenProcessEntity gradingScreenProcess(Double rawCoal, String processId) {
        GradingScreenProcessEntity gradingScreen = new GradingScreenProcessEntity();
        gradingScreen.setMaterialInput(rawCoal);
        // 理论矸石输出算法
        BigDecimal rowCoalNum = BigDecimal.valueOf(rawCoal);
        BigDecimal bigDecimalGangueOutput = rowCoalNum.multiply(BigDecimal.valueOf(0.1));
        double gangueOutput = bigDecimalGangueOutput.doubleValue();
        // 理论矿产lt50mm算法
        BigDecimal bigDecimalLt50mm = rowCoalNum.subtract(bigDecimalGangueOutput).multiply(BigDecimal.valueOf(0.4));
        double lt50mm = bigDecimalLt50mm.doubleValue();
        // 理论矿产gt50,lt200算法
        double mineralOutput = rowCoalNum.subtract(bigDecimalGangueOutput).subtract(bigDecimalLt50mm).doubleValue();

        gradingScreen.setGangueOutput(gangueOutput);
        gradingScreen.setLt50mmMineral(lt50mm);
        gradingScreen.setMineralOutput(mineralOutput);
        gradingScreen.setId(getRandomId());
        gradingScreen.setProcessId(processId);

        // 分级筛理论流程数据入库
        gradingScreenDao.addProcess(gradingScreen);

        this.gangue += gangueOutput;

        return gradingScreen;
    }

    /**
     * 跳汰机
     * @param materialInput
     * @param processId
     * @return
     */
    private JigProcessEntity jigProcess(Double materialInput, String processId) {
        JigProcessEntity jigProcess = new JigProcessEntity();
        // 矸石输出理论算法
        BigDecimal bgMaterialInput = BigDecimal.valueOf(materialInput);
        BigDecimal bgGangue = bgMaterialInput.multiply(BigDecimal.valueOf(0.1));
        double gangue = bgGangue.doubleValue();
        // 矿物输出算法
        double mineralOutput = bgMaterialInput.subtract(bgGangue).doubleValue();

        jigProcess.setMaterialInput(materialInput);
        jigProcess.setProcessId(processId);
        jigProcess.setId(getRandomId());
        jigProcess.setGangueOutput(gangue);
        jigProcess.setMineralOutput(mineralOutput);
        jigDao.addProcess(jigProcess);

        this.gangue += gangue;

        return jigProcess;
    }

    /**
     * 离心机
     * @param materialInput
     * @param processId
     * @return
     */
    private CentrifugeProcessEntity centrifugeProcess(Double materialInput, String processId) {
        CentrifugeProcessEntity centrifugeProcess = new CentrifugeProcessEntity();
        // 理论水输出
        BigDecimal bdMaterialInput = BigDecimal.valueOf(materialInput);
        BigDecimal bdWater = bdMaterialInput.multiply(BigDecimal.valueOf(0.1)).add(BigDecimal.valueOf(WATER_INPUT_ONE_TON));
        double water = bdWater.doubleValue();

        double coal = bdMaterialInput.subtract(bdMaterialInput.multiply(BigDecimal.valueOf(0.1))).doubleValue();

        centrifugeProcess.setProcessId(processId);
        centrifugeProcess.setId(getRandomId());
        centrifugeProcess.setMaterialInput(materialInput);
        centrifugeProcess.setWaterOutput(water);
        centrifugeProcess.setCoalOutput(coal);
        centrifugeDao.addProcess(centrifugeProcess);

        this.mediumCoal += coal;

        return centrifugeProcess;
    }

    /**
     * 脱泥筛
     * @param materialInput
     * @param processId
     * @return
     */
    private DeslimingScreenProcessEntity deslimingScreenProcess(Double materialInput, String processId) {
        DeslimingScreenProcessEntity deslimingScreenProcessEntity = new DeslimingScreenProcessEntity();
        deslimingScreenProcessEntity.setProcessId(processId);
        deslimingScreenProcessEntity.setId(getRandomId());
        deslimingScreenProcessEntity.setMaterialInput(materialInput);
        // 计算小于1mm矿物理论值
        BigDecimal bdMaterialInput = BigDecimal.valueOf(materialInput);
        BigDecimal bdLt1mm = bdMaterialInput.multiply(BigDecimal.valueOf(0.4));
        double lt1mm = bdLt1mm.doubleValue();
        // 计算大于1mm矿物理论值
        double gt1mm = bdMaterialInput.subtract(bdLt1mm).doubleValue();
        deslimingScreenProcessEntity.setLt1mmCoal(lt1mm);
        deslimingScreenProcessEntity.setGt1mmCoal(gt1mm);

        deslimingScreenDao.addProcess(deslimingScreenProcessEntity);

        return deslimingScreenProcessEntity;
    }

    /**
     * 分级旋流器
     * @param input
     * @param processId
     * @return
     */
    private HierarchicalCycloneProcessEntity hierarchicalCycloneProcess(Double input, String processId) {
        HierarchicalCycloneProcessEntity hierarchicalCycloneProcessEntity = new HierarchicalCycloneProcessEntity();
        hierarchicalCycloneProcessEntity.setProcessId(processId);
        hierarchicalCycloneProcessEntity.setId(getRandomId());
        hierarchicalCycloneProcessEntity.setMaterialInput(input);

        // 计算小于0.25mm物理理论值
        BigDecimal bdInput = BigDecimal.valueOf(input);
        BigDecimal bdLt025 = bdInput.multiply(BigDecimal.valueOf(0.3));
        double lt025 = bdLt025.doubleValue();

        // 计算大于0.25mm物理理论值
        double gt025 = bdInput.subtract(bdLt025).doubleValue();
        hierarchicalCycloneProcessEntity.setLt025Coal(lt025);
        hierarchicalCycloneProcessEntity.setGt025Coal(gt025);

        hierarchicalCycloneDao.addProcess(hierarchicalCycloneProcessEntity);

        return hierarchicalCycloneProcessEntity;
    }

    /**
     * 浮选机
     * @param input
     * @param processId
     * @return
     */
    private FloatationMachineProcessEntity floatationMachineProcess(Double input, String processId) {
        FloatationMachineProcessEntity floatationMachineProcessEntity = new FloatationMachineProcessEntity();
        floatationMachineProcessEntity.setProcessId(processId);
        floatationMachineProcessEntity.setId(getRandomId());
        floatationMachineProcessEntity.setMaterialInput(input);

        // 精煤理论算法
        BigDecimal bdInput = BigDecimal.valueOf(input);
        BigDecimal bdCleanCoal = bdInput.multiply(BigDecimal.valueOf(0.92));
        double cleanCoal = bdCleanCoal.doubleValue();

        // 杂质理论算法
        double impurityOutput = bdInput.subtract(bdCleanCoal).doubleValue();

        floatationMachineProcessEntity.setCleanCoalOutput(cleanCoal);
        floatationMachineProcessEntity.setImpurityOutput(impurityOutput);

        floatationDao.addProcess(floatationMachineProcessEntity);

        this.cleanCoal += cleanCoal;

        return floatationMachineProcessEntity;
    }

    /**
     * TBS
     * @param input
     * @param processId
     * @return
     */
    private TBSProcessEntity tbsProcess(Double input, String processId) {
        TBSProcessEntity tbsProcessEntity = new TBSProcessEntity();
        tbsProcessEntity.setProcessId(processId);
        tbsProcessEntity.setId(getRandomId());
        tbsProcessEntity.setMaterialInput(input);
        // 精矿获得算法
        BigDecimal bdInput = BigDecimal.valueOf(input);
        BigDecimal bdCleanCoal = bdInput.multiply(BigDecimal.valueOf(0.88));
        double cleanCoal = bdCleanCoal.doubleValue();

        // 粗矿获得算法
        double coarseOre = bdInput.subtract(bdCleanCoal).doubleValue();

        tbsProcessEntity.setCleanCoalOutput(cleanCoal);
        tbsProcessEntity.setCoarseOreOutput(coarseOre);

        tbsDao.addProcess(tbsProcessEntity);

        return tbsProcessEntity;
    }

    /**
     * 直线筛
     * @param input
     * @param processId
     * @return
     */
    private LinearScreenProcessEntity linearScreenProcess(Double input, String processId) {
        LinearScreenProcessEntity linearScreenProcessEntity = new LinearScreenProcessEntity();
        linearScreenProcessEntity.setProcessId(processId);
        linearScreenProcessEntity.setId(getRandomId());
        linearScreenProcessEntity.setMaterialInput(input);
        // 晒上精煤算法
        BigDecimal bdInput = BigDecimal.valueOf(input);
        BigDecimal bdCleanCoalOutput = bdInput.multiply(BigDecimal.valueOf(0.98));
        double cleanCoal = bdCleanCoalOutput.doubleValue();

        // 晒下粗矿算法
        double impurityOutput = bdInput.subtract(bdCleanCoalOutput).doubleValue();

        linearScreenProcessEntity.setCleanCoalOutput(cleanCoal);
        linearScreenProcessEntity.setImpurityOutput(impurityOutput);

        linearScreenDao.addProcess(linearScreenProcessEntity);

        return linearScreenProcessEntity;

    }

    /**
     * 弧形筛
     * @param input
     * @param processId
     * @return
     */
    private CurvedScreenProcessEntity curvedScreenProcess(Double input, String processId) {
        CurvedScreenProcessEntity curvedScreenProcessEntity = new CurvedScreenProcessEntity();
        curvedScreenProcessEntity.setProcessId(processId);
        curvedScreenProcessEntity.setId(getRandomId());
        curvedScreenProcessEntity.setMaterialInput(input);

        // 筛上精煤算法
        BigDecimal bdInput = BigDecimal.valueOf(input);
        BigDecimal bdCleanCoal = bdInput.multiply(BigDecimal.valueOf(0.95));
        double cleanCoal = bdCleanCoal.doubleValue();

        // 晒下杂质算法
        double impurityOutput = bdInput.subtract(bdCleanCoal).doubleValue();

        curvedScreenProcessEntity.setCleanCoalOutput(cleanCoal);
        curvedScreenProcessEntity.setImpurityOutput(impurityOutput);

        curvedScreenDao.addProcess(curvedScreenProcessEntity);

        return curvedScreenProcessEntity;
    }

    /**
     * 重介旋流器
     * @param input
     * @param processId
     * @return
     */
    private DenseMediumCycloneProcessEntity denseMediumCycloneProcess(Double input, String processId) {
        DenseMediumCycloneProcessEntity denseMediumCycloneProcessEntity = new DenseMediumCycloneProcessEntity();
        denseMediumCycloneProcessEntity.setProcessId(processId);
        denseMediumCycloneProcessEntity.setId(getRandomId());
        denseMediumCycloneProcessEntity.setMaterialInput(input);
        // 精煤算法
        BigDecimal bdInput = BigDecimal.valueOf(input);
        BigDecimal bdCleanCoal = bdInput.multiply(BigDecimal.valueOf(0.93));
        double cleanCoal = bdCleanCoal.doubleValue();

        // 煤矸混合物
        double coalGangueMixture = bdInput.subtract(bdCleanCoal).doubleValue();

        denseMediumCycloneProcessEntity.setCleanCoal(cleanCoal);
        denseMediumCycloneProcessEntity.setCoalGangueMixture(coalGangueMixture);

        denseMediumCycloneDao.addProcess(denseMediumCycloneProcessEntity);

        return denseMediumCycloneProcessEntity;

    }

    /**
     * 脱介筛
     * @param input
     * @param processId
     * @return
     */
    private DetachmentScreenProcessEntity detachmentScreenProcess(Double input, String processId) {
        DetachmentScreenProcessEntity detachmentScreenProcessEntity = new DetachmentScreenProcessEntity();
        detachmentScreenProcessEntity.setProcessId(processId);
        detachmentScreenProcessEntity.setId(getRandomId());
        detachmentScreenProcessEntity.setMaterialInput(input);

        // 精煤算法
        BigDecimal bdInput = BigDecimal.valueOf(input);
        BigDecimal bdCleanCoal = bdInput.multiply(BigDecimal.valueOf(0.9));
        double cleanCoal = bdCleanCoal.doubleValue();

        // 介质算法
        double media = bdInput.subtract(bdCleanCoal).doubleValue();

        detachmentScreenProcessEntity.setCleanCoalOutput(cleanCoal);
        detachmentScreenProcessEntity.setMediaOutput(media);

        detachmentScreenDao.addProcess(detachmentScreenProcessEntity);

        return detachmentScreenProcessEntity;

    }

    /**
     * 旋流器
     * @param input
     * @param processId
     * @return
     */
    private CycloneProcessEntity cycloneProcess(Double input, String processId) {
        CycloneProcessEntity cycloneProcessEntity = new CycloneProcessEntity();
        cycloneProcessEntity.setId(getRandomId());
        cycloneProcessEntity.setProcessId(processId);
        cycloneProcessEntity.setMaterialInput(input);
        // 计算中煤产量
        BigDecimal bdInput = BigDecimal.valueOf(input);
        BigDecimal bdMediumCoal = bdInput.multiply(BigDecimal.valueOf(0.92));
        double mediumCoal = bdMediumCoal.doubleValue();

        // 计算矸石量
        double gangue = bdInput.subtract(bdMediumCoal).doubleValue();

        cycloneProcessEntity.setMediumCoal(mediumCoal);
        cycloneProcessEntity.setGangue(gangue);

        cycloneProcessDao.addProcess(cycloneProcessEntity);

        return cycloneProcessEntity;

    }

    /**
     * 获取uuid
     * @return
     */
    private String getRandomId() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }
}
